#pragma once
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/web/mime/multipart/Multipart.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "../dto/AlarmDto.h"
#include "../dto/CountDto.h"
#include "../dto/AlarmListDto.h"
#include "../vo/AlarmVo.h"
#include "../service/AlarmService.h"
#include "../ai/Broadcast.h"
#include "../AiBox.h"

#include OATPP_CODEGEN_BEGIN(ApiController)

/**
 * 报警控制器
 */
class AlarmController : public oatpp::web::server::api::ApiController {
public:
	AlarmController(const std::shared_ptr<ObjectMapper>& objectMapper)
		: oatpp::web::server::api::ApiController(objectMapper)
	{}

	/*
	* 报警图片预览
	*/
	ENDPOINT("GET", "/alarm/image", getAlarmImage,
		QUERY(String, id))
	{
		AlarmInfo alarmInfo;
		alarmInfo.SetId(id.getValue(""));

		AlarmService alarmService;
		if (!alarmService.Find(alarmInfo))
		{
			return createResponse(Status::CODE_404, "invalid id:" + alarmInfo.GetId());
		}

		std::string path = alarmInfo.GetImagePath();
		if (!FileUtil::Exists(path) || FileUtil::IsDir(path))
		{
			return ResponseFactory::createResponse(Status::CODE_404, "invalid path:" + path);
		}

		std::string content = FileUtil::Read(path);
		return createResponse(Status::CODE_200, content);
	}

	/*
	* 报警录像预览
	*/
	ENDPOINT("GET", "/alarm/record", getAlarmRecord,
		QUERY(String, id))
	{
		AlarmInfo alarmInfo;
		alarmInfo.SetId(id.getValue(""));

		AlarmService alarmService;
		if (!alarmService.Find(alarmInfo))
		{
			return createResponse(Status::CODE_404, "invalid id:" + alarmInfo.GetId());
		}

		std::string path = alarmInfo.GetRecordPath();
		if (!FileUtil::Exists(path) || FileUtil::IsDir(path))
		{
			return ResponseFactory::createResponse(Status::CODE_404, "invalid path:" + path);
		}

		std::string content = FileUtil::Read(path);
		return createResponse(Status::CODE_200, content);
	}

	/*
	* 获取最近报警
	*/
	ENDPOINT("GET", "/alarm/latest", getLatestAlarm,
		QUERY(String, startTime))
	{
		// 返回操作结果
		auto result = AlarmListDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 获取查询开始时间
		std::string time = startTime.getValue("");
		if (time.find("+") != -1)
		{
			time = TextUtil::get_mutable_instance().ReplaceAll(time, "+", " ");
		}
		DateTime lastTime = DateTime::Now();
		lastTime.From(time);

		// 初始化空列表
		oatpp::List<oatpp::Object<AlarmVo>> items({});

		// 查询最近报警
		ALARM_LIST alarms = Broadcast::get_mutable_instance().Latest(lastTime);
		for (size_t index = 0; index < alarms.size(); ++index)
		{
			auto config = AlarmVo::createShared();
			config->id = alarms[index].id;
			config->deviceId = alarms[index].deviceId;
			config->deviceName = alarms[index].deviceName;
			config->alarmType = alarms[index].alarmType;
			config->alarmInfo = alarms[index].alarmInfo;
			config->alarmTime = alarms[index].alarmTime.ToNormalString();
			config->imageUrl = alarms[index].imageUrl;
			items->emplace(items->end(), config);
		}

		// 返回报警列表
		result->error = 0;
		result->description = "success";
		result->value = items;
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 删除报警
	*/
	ENDPOINT("DELETE", "/alarm/delete", deleteAlarm,
		HEADER(String, authorization, "Authorization"),
		QUERY(String, id)) {

		// 返回操作结果
		auto result = SimpleDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 报警信息
		AlarmInfo alarm;
		alarm.SetId(id.getValue(""));

		// 删除报警
		AlarmService alarmService;
		if (alarmService.Find(alarm))
		{
			if (!alarm.GetImagePath().empty())
			{
				Box::get_mutable_instance().GetFileClear()->AddFile(alarm.GetImagePath());
			}
			if (!alarm.GetRecordPath().empty())
			{
				Box::get_mutable_instance().GetFileClear()->AddFile(alarm.GetRecordPath());
			}
			alarmService.Delete(alarm);
		}

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		result->value = alarm.GetId();
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 获取报警数量
	*/
	ENDPOINT("GET", "/alarm/count", getAlarmCount,
		HEADER(String, authorization, "Authorization"),
		REQUEST(std::shared_ptr<IncomingRequest>, request)) {

		// 获取筛选参数
		std::string deviceId = request->getQueryParameter("deviceId").getValue("");
		std::string startTime = request->getQueryParameter("startTime").getValue("");
		std::string endTime = request->getQueryParameter("endTime").getValue("");
		std::string alarmType = request->getQueryParameter("alarmType").getValue("");
		std::string upload = request->getQueryParameter("upload").getValue("");
		// 2024-04-06+00:00:00
		if (startTime.find("+") != -1)
		{
			startTime = TextUtil::get_mutable_instance().ReplaceAll(startTime, "+", " ");
		}
		if (endTime.find("+") != -1)
		{
			endTime = TextUtil::get_mutable_instance().ReplaceAll(endTime, "+", " ");
		}

		// 返回操作结果
		auto result = CountDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		if (startTime.empty() && endTime.empty())
		{
			result->description = "查询起止时间无效!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查询报警数量
		AlarmService alarmService;
		int count = alarmService.Count(deviceId, startTime, endTime, alarmType, upload);

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		result->value = count;
		return createDtoResponse(Status::CODE_200, result);
	}

	/**
	 * 查询报警列表
	 */
	ENDPOINT("GET", "/alarm/list", listAlarm,
		HEADER(String, authorization, "Authorization"),
		QUERY(Int32, pageIndex),
		QUERY(Int32, pageSize),
		REQUEST(std::shared_ptr<IncomingRequest>, request)) {

		// 获取筛选参数
		std::string deviceId = request->getQueryParameter("deviceId").getValue("");
		std::string startTime = request->getQueryParameter("startTime").getValue("");
		std::string endTime = request->getQueryParameter("endTime").getValue("");
		std::string alarmType = request->getQueryParameter("alarmType").getValue("");
		std::string upload = request->getQueryParameter("upload").getValue("");
		// 2024-04-06+00:00:00
		if (startTime.find("+") != -1)
		{
			startTime = TextUtil::get_mutable_instance().ReplaceAll(startTime, "+", " ");
		}
		if (endTime.find("+") != -1)
		{
			endTime = TextUtil::get_mutable_instance().ReplaceAll(endTime, "+", " ");
		}

		// 返回操作结果
		auto result = AlarmListDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		if (startTime.empty() && endTime.empty())
		{
			result->description = "查询起止时间无效!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查询报警信息
		int index = (pageIndex.getValue(1) - 1) * pageSize.getValue(10);
		int size = pageSize.getValue(10);

		std::vector<AlarmInfo> alarms;
		AlarmService alarmService;
		alarmService.FindPage(index, size, deviceId, startTime, endTime, alarmType, upload, alarms);

		// 初始化空列表
		oatpp::List<oatpp::Object<AlarmVo>> items({});

		// 填充报警列表
		for (size_t index = 0; index < alarms.size(); ++index)
		{
			auto alarm = AlarmVo::createShared();
			alarm->id = alarms[index].GetId();
			alarm->deviceId = alarms[index].GetDeviceId();
			alarm->deviceName = alarms[index].GetDeviceName();
			alarm->alarmType = alarms[index].GetAlarmType();
			alarm->alarmInfo = alarms[index].GetAlarmInfo();
			alarm->alarmTime = alarms[index].GetAlarmTime().ToNormalString();
			alarm->upload = alarms[index].GetUpload();
			alarm->uploadTime = alarms[index].GetUploadTime().ToNormalString();
			alarm->uploadCount = alarms[index].GetUploadCount();
			alarm->imagePath = alarms[index].GetImagePath();
			alarm->imageUrl = alarms[index].GetImageUrl();
			alarm->uploadRecord = alarms[index].GetUploadRecord();
			alarm->recordPath = alarms[index].GetRecordPath();
			alarm->recordUrl = alarms[index].GetRecordUrl();
			items->emplace(items->end(), alarm);
		}

		// 返回报警列表
		result->error = 0;
		result->description = "success";
		result->value = items;
		return createDtoResponse(Status::CODE_200, result);
	}
};

#include OATPP_CODEGEN_END(ApiController)